package com.heima.wemedia.service.impl;
import java.util.Date;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustException;
import com.heima.common.exception.CustomException;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.WmThreadLocalUtils;
import com.heima.model.wemedia.dtos.WmMaterialDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class WmMaterialServiceImpl extends ServiceImpl<WmMaterialMapper, WmMaterial> implements WmMaterialService {
    @Autowired
    FileStorageService fileStorageService;
    @Value("${file.oss.prefix}")
    String prefix;
    @Value("${file.oss.web-site}")
    String webSite;
    private Integer count;

    @Override
    public ResponseResult uploadPicture(MultipartFile multipartFile) {
        //1.检查参数（校验图片格式）
        if (multipartFile==null||multipartFile.getSize()==0) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID,"请上传正确的文件");
        }
        WmUser user = WmThreadLocalUtils.getUser();
        if (user==null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        //获取原始文件名称
        String originalFilename = multipartFile.getOriginalFilename();
        //2.上传文件到阿里云oss
        //substring截取掉str从首字母起长度为beginIndex的字符串，将剩余字符串赋值给str
        //文件名称：获取原始后缀 .jpg  .png 等
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //新文件名称：随机生成UUID + 后缀
        //UUID会以“-”分割字符所以需要替换掉所有的-
        String fileName = UUID.randomUUID().toString().replaceAll("-","") + suffix;
        //调用上传方法
        //fileStorageService.store参数1：oos文件夹的名称
        try {
            //返回值是文件在oos文件夹中的全路径
            String store = fileStorageService.store("material", fileName, multipartFile.getInputStream());
            //3.创建material实体类
            WmMaterial wmMaterial = new WmMaterial();
            wmMaterial.setUserId(user.getId());
            wmMaterial.setUrl(store);
            wmMaterial.setType((short)0);
            wmMaterial.setIsCollection((short)0);
            wmMaterial.setCreatedTime(new Date());
            //4.保存素材
            save(wmMaterial);
            //5.返回结果  需要在url上添加访问前缀  用于前端回显图片
            wmMaterial.setUrl(webSite+wmMaterial.getUrl());
            return ResponseResult.okResult(wmMaterial);
        } catch (IOException e) {
            e.printStackTrace();
            throw new CustomException(AppHttpCodeEnum.SERVER_ERROR,"服务端出现异常，上传素材失败");
        }
    }

    @Override
    public ResponseResult findList(WmMaterialDto dto) {
        //1.检查参数
        if (dto==null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.分页参数校验
        dto.checkParam();
        //3.检查作者信息
        WmUser user = WmThreadLocalUtils.getUser();
        if (user==null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        //4.添加查询条件（收藏）
        LambdaQueryWrapper<WmMaterial> queryWrapper = new LambdaQueryWrapper<>();
        if (dto.getIsCollection()!=null&&dto.getIsCollection()==1) {
            queryWrapper.eq(WmMaterial::getIsCollection,dto.getIsCollection());
        }
        //5.按照时间降序排列
            //查询条件是用户的Id相互比较
        queryWrapper.eq(WmMaterial::getUserId,user.getId());
        queryWrapper.orderByDesc(WmMaterial::getCreatedTime);
        IPage<WmMaterial> page = new Page<>(dto.getPage(),dto.getSize());
        IPage<WmMaterial> result = page(page, queryWrapper);
        List<WmMaterial> records = result.getRecords();
        for (WmMaterial record : records) {
            record.setUrl(webSite+record.getUrl());
        }
        //6.返回结果，图片加上前缀返回路径
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), result.getTotal(), records);
        return pageResponseResult;
    }
    @Autowired
    WmNewsMaterialMapper wmNewsMaterialMapper;
    @Override
    public ResponseResult delPicture(Integer id) {
        //1.检查参数
        if (id==null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.检查是否被引用，如果被引用则不能删除
        WmMaterial wmMaterial = getById(id);
        if (wmMaterial==null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        LambdaQueryWrapper<WmNewsMaterial> queryWrapper = Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getMaterialId, wmMaterial.getId());
        int count = wmNewsMaterialMapper.selectCount(queryWrapper);
        if (count>0) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW,"素材已经被文章引用不允许删除");
        }
        //3.删除素材库，删除图片oss
        removeById(id);
        fileStorageService.delete(wmMaterial.getUrl());
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateStatus(Integer id, Short type) {
        //1.检查参数
        if (id==null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (type.intValue()!=0&&type.intValue()!=1) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.根据状态设置收藏和取消收藏
        //更新条件需要检索对应的用户ID和素材本身的ID
        WmUser user = WmThreadLocalUtils.getUser();
        LambdaUpdateWrapper<WmMaterial> updateWrapper = Wrappers.<WmMaterial>lambdaUpdate()
                                                                .set(WmMaterial::getType, type)
                                                                .eq(WmMaterial::getId,id)
                                                                .eq(WmMaterial::getUserId,user.getId());
        update(updateWrapper);
        return ResponseResult.okResult();
    }
}
